home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Games / SpriteFight 2002 v2.0a1 / Spritez.c < prev    next >
Encoding:
Text File  |  1996-04-30  |  21.4 KB  |  711 lines  |  [TEXT/KAHL]

  1. // Spritez.c
  2. // by Stefan C. Sinclair Copyright © 1995-1996 All rights reserved.
  3.  
  4. #include "SpriteError.h"
  5. #include "Spritez.h"
  6. #include "Application.h"
  7. #include "SpriteFile.h"
  8.  
  9. extern CWindowPtr    gWindowP;
  10. extern SndChannelPtr gSoundChanP1, gSoundChanP2, gSoundChanGame;
  11. extern short    gFrameAdvanceTime;
  12. extern short    gPlayer1Controller, gPlayer2Controller;
  13. extern SpriteFileRec    gPlayer1File, gPlayer2File;
  14. extern CombatZoneFileRec gCombatZoneFile;
  15. extern Point    player1TopLeft;
  16. extern Point    player2TopLeft;
  17. extern SpriteGameRec spriteGame;
  18. extern Boolean gSecretCode[kNumSecretCodes];
  19.  
  20. Handle    gP1SoundH[kNumSpriteSounds], gP2SoundH[kNumSpriteSounds];
  21. Handle    musicH;
  22. RgnHandle gWorkRgn;
  23. short gWinnerSprite;
  24. short gSpriteHeight, gSpriteWidth;
  25. short gPICTFileRefNum;
  26. SpriteGameRec spriteGame;
  27. Rect    gPlayer1DamageRect, gPlayer2DamageRect;
  28.  
  29. OSErr CombatCommand(Boolean *player1Victorious)
  30. {
  31.     unsigned long ticks, startTicks;
  32.     long    seconds, oldSeconds;
  33.     OSErr    err = noErr;
  34.     short    i, combatRoundTime;
  35.     Rect    timeRect;
  36.     Str255    timeStr;
  37.     SpritePtr    backgroundSprite;
  38.     Boolean haveEvent;
  39.     EventRecord event;
  40.  
  41.     // Some initializations
  42.     FlushEvents(everyEvent, 0);
  43.     InitSoundChannel(&gSoundChanP1);
  44.     InitSoundChannel(&gSoundChanP2);
  45.     InitSoundChannel(&gSoundChanGame);
  46.     gWorkRgn = NULL;
  47.     gSpriteHeight = 128;
  48.     gSpriteWidth = 128;
  49.     gPlayer1DamageRect.top = kLifeRectTop;
  50.     gPlayer1DamageRect.bottom = kLifeRectBottom;
  51.     gPlayer1DamageRect.left = kP1LifeRectLeft + kSpriteLife; // zero damage
  52.     gPlayer1DamageRect.right = kP1LifeRectRight;
  53.     gPlayer2DamageRect.top = kLifeRectTop;
  54.     gPlayer2DamageRect.bottom = kLifeRectBottom;
  55.     gPlayer2DamageRect.left = kP2LifeRectLeft + kSpriteLife; // zero damage
  56.     gPlayer2DamageRect.right = kP2LifeRectRight;
  57.     
  58.     // Here we go.
  59.     // Play a movie! Yay!
  60.     //PlaySpriteMovie(gCombatZoneFile);
  61.     // Create the players
  62.     gWinnerSprite = -1; // No winner yet.
  63.     // •••••••••••••••••••••••••••••••• Create sprite world
  64.     StartWaiting();
  65.     err = CreateSpriteGame(&spriteGame);
  66.     if(err != noErr)
  67.     {
  68.         DoError(kCouldNotCreateSprites, FALSE);
  69.         StopWaiting();
  70.         return err;
  71.     }
  72.     
  73.     StopWaiting();
  74.  
  75.     timeRect.top = kTimeRectTop;
  76.     timeRect.left = kTimeRectLeft;
  77.     timeRect.bottom = kTimeRectBottom;
  78.     timeRect.right = kTimeRectRight;
  79.     
  80.     // Begin!
  81.     if((**spriteGame.spriteWorldP->backFrameP->framePort.colorGrafP->portPixMap).pixelSize != 8)
  82.     {
  83.         DoError(kNeedMonitor256Colors, FALSE);
  84.     }
  85.     HideCursor();
  86.     SWLockSpriteWorld(spriteGame.spriteWorldP);
  87.     SWUpdateSpriteWorld(spriteGame.spriteWorldP);
  88.     ticks = 0;
  89.     seconds = oldSeconds = 0;
  90.     startTicks = TickCount();
  91.     combatRoundTime = (gSecretCode[kDoubleTimeCode] ?
  92.             (2*kNumberOfSecondsPerRound) : kNumberOfSecondsPerRound);
  93.     NumToString((combatRoundTime - seconds), timeStr);
  94.     DRAW_TIME
  95.     while(ticks < (60 * combatRoundTime))
  96.     {
  97.         /*** Draw Elapsed Time ***/
  98.         ticks = TickCount() - startTicks;
  99.         seconds = ticks / 60;
  100.         if(seconds != oldSeconds)
  101.         {
  102.             oldSeconds = seconds;
  103.             NumToString((kNumberOfSecondsPerRound - seconds), timeStr);
  104.             DRAW_TIME
  105.         }
  106.         SWCollideSpriteLayer(spriteGame.playerLayerP, spriteGame.playerLayerP);
  107.         SWProcessSpriteWorld(spriteGame.spriteWorldP);
  108.         SWAnimateSpriteWorld(spriteGame.spriteWorldP);
  109.         // Music
  110.         if(!gSecretCode[kNoBGMusicCode])
  111.             LoopSound(musicH, gSoundChanGame);
  112.         // Uncomment to let menu clock update!
  113.         //haveEvent = WaitNextEvent(everyEvent, &event, 0, NULL);
  114.         if(gWinnerSprite >= 0)
  115.             goto BATTLE_IS_OVER; // This will make sure we kick out of the loop!
  116.     }
  117.     BATTLE_IS_OVER:
  118.     // Turn off the music
  119.     if(!gSecretCode[kNoBGMusicCode])
  120.         StopPlayingSound(gSoundChanGame);
  121.         
  122.     SWUnlockSpriteWorld(spriteGame.spriteWorldP);
  123.     // Did both sprites survive the battle?
  124.     if(gWinnerSprite < 0)
  125.     {
  126.         gWinnerSprite = DetermineWinner(spriteGame.spriteWorldP);
  127.         SpriteFuneral(gWinnerSprite);
  128.     }
  129.     else
  130.         SpriteFuneral(gWinnerSprite);
  131.     // Tell the caller who won
  132.     switch(gWinnerSprite)
  133.     {
  134.         case kPlayer1Sprite:
  135.         case kComputer1Sprite:
  136.             *player1Victorious = TRUE;
  137.             break;
  138.         default:
  139.             *player1Victorious = FALSE;
  140.             break;
  141.     }
  142.     // Clean up 'internal' memory
  143.     DISPOSAL:
  144.     ShowCursor();
  145.     MyDisposeSpriteGame(&spriteGame);
  146.     // Dispose of music
  147.     if(!gSecretCode[kNoBGMusicCode])
  148.     {
  149.         HUnlock(musicH);
  150.         DisposeHandle(musicH);
  151.     }
  152.     
  153.     err = MemError();
  154.     if(err != noErr)
  155.         DoError(kGeneralMemoryError, TRUE);
  156.     
  157.     // Mark window for update
  158.     InvalRect(&gWindowP->portRect);
  159.     
  160.     // Kill Sound Channels
  161.     KillSoundChannel(&gSoundChanP1);
  162.     KillSoundChannel(&gSoundChanP2);
  163.     KillSoundChannel(&gSoundChanGame);
  164.     
  165.     // reset secret code flags
  166.     for(i=0; i<kNumSecretCodes; i++)
  167.         gSecretCode[i] = FALSE;
  168.     
  169.     FlushEvents(everyEvent, 0);
  170.     return err;
  171. }
  172.  
  173. OSErr CreateSpriteGame(SpriteGamePtr gamePtr)
  174. {
  175.     OSErr err = noErr;
  176.     SpritePtr spriteArray[kNumberOfSprites];
  177.     short i, foregroundSpriteID, backgroundSpriteID;
  178.     short oldResRefNum, curResRefNum, gPICTFileRefNum;
  179.     Rect worldRect, hourGlassRect, damageRect;
  180.     unsigned char    *spriteDataPtr; // use as an array of 8 u. chars.
  181.     PicHandle    BackGroundPict, timePict;
  182.     CQDProcsPtr    savedProcs;
  183.     CQDProcs    myProcs;    /*use CQDProcs for a color window*/
  184.     long    longCount,myEOF,filePos;
  185.     QDPutPicUPP    myGetPICTProc;
  186.  
  187.     gWorkRgn = NewRgn();
  188.     SetPort((GrafPtr)gWindowP);
  189.     worldRect = gWindowP->portRect;
  190.  
  191.     if (err == noErr)
  192.         err = SWEnterSpriteWorld();
  193.     if (err == noErr)
  194.     // create the sprite world
  195.         err = SWCreateSpriteWorldFromWindow(&gamePtr->spriteWorldP, gWindowP, NULL);
  196.     if (err == noErr)
  197.     {
  198.         // create the sprite layers
  199.         err = SWCreateSpriteLayer(&gamePtr->playerLayerP);
  200.         if(err == noErr)
  201.             err = SWCreateSpriteLayer(&gamePtr->backgroundLayerP);
  202.         if(err == noErr)
  203.             err = SWCreateSpriteLayer(&gamePtr->foregroundLayerP);
  204.     }
  205.     
  206.     if (err == noErr)
  207.     {
  208.         // Load Background music
  209.         oldResRefNum = CurResFile();
  210.         curResRefNum = HOpenResFile(gCombatZoneFile.sfFile.vRefNum,
  211.                     gCombatZoneFile.sfFile.parID,gCombatZoneFile.sfFile.name,
  212.                     fsRdPerm);
  213.         err = ((ResError()!=noErr) || curResRefNum < 0);
  214.         
  215.         UseResFile(curResRefNum);
  216.         if(!gSecretCode[kNoBGMusicCode])
  217.         {
  218.             musicH = Get1Resource('snd ', kBGMusicResID);
  219.             if(musicH == NULL)
  220.                 gSecretCode[kNoBGMusicCode] = TRUE; // no music!
  221.             else
  222.             {
  223.                 DetachResource(musicH);
  224.                 MoveHHi(musicH);
  225.                 HLock(musicH);
  226.             }
  227.         }
  228.         CloseResFile(curResRefNum);
  229.         UseResFile(oldResRefNum);
  230.         
  231.         // Get Background PICT
  232.         err = FSpOpenDF(&gCombatZoneFile.sfFile, fsRdPerm,&gPICTFileRefNum);
  233.         if(err != noErr)
  234.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  235.         else
  236.             err = GetEOF(gPICTFileRefNum,&myEOF); // get EOF for later check
  237.         if(err != noErr)
  238.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  239.         else
  240.             err = SetFPos(gPICTFileRefNum,fsFromStart,512);//skip header
  241.         if(err != noErr)
  242.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  243.         // read in the (obsolete) size word and the picFrame
  244.         longCount = myEOF - 512;
  245.         BackGroundPict = (PicHandle)NewHandleClear(longCount);
  246.         if(BackGroundPict != NULL)
  247.             HLock((Handle)BackGroundPict);
  248.         else
  249.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  250.         err = FSRead(gPICTFileRefNum,&longCount,(Ptr)*BackGroundPict);
  251.         if(err != noErr)
  252.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  253.         HUnlock((Handle)BackGroundPict);
  254.         err = GetFPos(gPICTFileRefNum,&filePos);    // get position for check
  255.         if(err != noErr)
  256.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  257.         err = FSClose(gPICTFileRefNum);
  258.         if(err != noErr)
  259.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  260.         //Check for errors. if there wasn't enough room,
  261.         //DrawPicture will abort; the FILE position mark
  262.         //won't be at the end of the FILE.
  263.         if(filePos != myEOF)
  264.         {
  265.             DoError(kCouldNotCreateBackGroundSprite, FALSE);
  266.             err = 1;
  267.         }
  268.     }
  269.  
  270.     // •••••••••••••••••••••••••••••••• Create player 1 sprite
  271.     if (err == noErr)
  272.     {
  273.         oldResRefNum = CurResFile();
  274.         curResRefNum = HOpenResFile(gPlayer1File.sfFile.vRefNum,
  275.                     gPlayer1File.sfFile.parID,gPlayer1File.sfFile.name,
  276.                     fsRdPerm);
  277.         err = ((ResError()!=noErr) || curResRefNum < 0);
  278.     }
  279.     if (err == noErr) // Here, sprite is actually created
  280.     {
  281.         // create player 1 sprite
  282.         UseResFile(curResRefNum);
  283.         // PICT sprites
  284.         // The Warrior
  285.         err = SWCreateSpriteFromPictResource(&spriteArray[kPlayer1Sprite],
  286.             &gamePtr->spriteArray[kPlayer1Sprite],kFirstSpriteResNum, (kFirstSpriteResNum+kMaskFrameOffset),
  287.                 kNumberOfWarriorFrames,kRegionMask);
  288.         // ... and the projectile
  289.         if(err == noErr && !gSecretCode[kNoProjectileCode])
  290.             err = SWCreateSpriteFromPictResource(&spriteArray[kPlayer1ProjectileSprite],
  291.                 &gamePtr->spriteArray[kPlayer1ProjectileSprite],kFirstProjectileResNum, (kFirstProjectileResNum+kMaskFrameOffset),
  292.                     kNumberOfProjectileFrames,kRegionMask);
  293.         
  294.         // Get sounds
  295.         if(err == noErr)
  296.         {
  297.             for(i=0; i<kNumSpriteSounds; i++)
  298.             {
  299.                 gP1SoundH[i] = Get1Resource('snd ', i+kFirstSoundResID);
  300.                 if(gP1SoundH[i] == NULL)
  301.                     CantFindResource();
  302.                 DetachResource(gP1SoundH[i]);
  303.                 MoveHHi(gP1SoundH[i]);
  304.                 HLock(gP1SoundH[i]);
  305.             }
  306.         }
  307.         
  308.         CloseResFile(curResRefNum);
  309.         UseResFile(oldResRefNum);
  310.     }
  311.     else
  312.     {
  313.         DoError(kCouldNotCreatePlayer1Sprite, FALSE);
  314.         // dispose memory later.
  315.     }
  316.     
  317.     // •••••••••••••••••••••••••••••••• Create player 2 sprite
  318.     if (err == noErr)
  319.     {
  320.         oldResRefNum = CurResFile();
  321.         curResRefNum = HOpenResFile(gPlayer2File.sfFile.vRefNum,
  322.                     gPlayer2File.sfFile.parID,gPlayer2File.sfFile.name,
  323.                     fsRdPerm);
  324.         err = ((ResError()!=noErr)|| curResRefNum < 0);
  325.     }
  326.     if (err == noErr) // Here, sprite is actually created
  327.     {
  328.         // create player 2 sprite
  329.         UseResFile(curResRefNum);
  330.         // PICT sprites
  331.         // The Warrior
  332.         err = SWCreateSpriteFromPictResource(&spriteArray[kPlayer2Sprite],
  333.             &gamePtr->spriteArray[kPlayer2Sprite],kFirstSpriteResNum, (kFirstSpriteResNum+kMaskFrameOffset),
  334.                 kNumberOfWarriorFrames,kRegionMask);
  335.         // ... and the projectile
  336.         if(err == noErr && !gSecretCode[kNoProjectileCode])
  337.             err = SWCreateSpriteFromPictResource(&spriteArray[kPlayer2ProjectileSprite],
  338.                 &gamePtr->spriteArray[kPlayer2ProjectileSprite],kFirstProjectileResNum, (kFirstProjectileResNum+kMaskFrameOffset),
  339.                     kNumberOfProjectileFrames,kRegionMask);
  340.                 
  341.         // Get sounds
  342.         if(err == noErr)
  343.         {
  344.             for(i=0; i<kNumSpriteSounds; i++)
  345.             {
  346.                 gP2SoundH[i] = Get1Resource('snd ', i+kFirstSoundResID);
  347.                 if(gP2SoundH[i] == NULL)
  348.                     CantFindResource();
  349.                 DetachResource(gP2SoundH[i]);
  350.                 MoveHHi(gP2SoundH[i]);
  351.                 HLock(gP2SoundH[i]);
  352.             }
  353.         }
  354.         
  355.         CloseResFile(curResRefNum);
  356.         UseResFile(oldResRefNum);
  357.     }
  358.     else
  359.     {
  360.         DoError(kCouldNotCreatePlayer1Sprite, FALSE);
  361.         // dispose memory later.
  362.     }
  363.     
  364.     // Add background sprite if the secret code is activated
  365.     if(err == noErr && gSecretCode[kBGAnimationCode])
  366.     {
  367.         backgroundSpriteID = GetRandom(kFirstBackgroundSpriteID,kLastBackgroundSpriteID);
  368.         err = CreateBackgroundSprite(&gamePtr->spriteArray[kBackgroundSprite], backgroundSpriteID);
  369.     }
  370.     
  371.     // Add foreground sprite if the secret code is activated
  372.     if(err == noErr && gSecretCode[kFGAnimationCode])
  373.     {
  374.         foregroundSpriteID = GetRandom(kFirstForegroundSpriteID,kLastForegroundSpriteID);
  375.         err = CreateForegroundSprite(&gamePtr->spriteArray[kForegroundSprite], foregroundSpriteID);
  376.     }
  377.  
  378.     if (err == noErr)
  379.     {        
  380.         // Add sprites to layers
  381.         SWAddSprite(gamePtr->playerLayerP, &gamePtr->spriteArray[kPlayer1Sprite]);
  382.         SWAddSprite(gamePtr->playerLayerP, &gamePtr->spriteArray[kPlayer2Sprite]);
  383.         SWAddSprite(gamePtr->playerLayerP, &gamePtr->spriteArray[kPlayer1ProjectileSprite]);
  384.         SWAddSprite(gamePtr->playerLayerP, &gamePtr->spriteArray[kPlayer2ProjectileSprite]);
  385.         if(gSecretCode[kBGAnimationCode])
  386.             SWAddSprite(gamePtr->backgroundLayerP,&gamePtr->spriteArray[kBackgroundSprite]);
  387.         if(gSecretCode[kFGAnimationCode])
  388.             SWAddSprite(gamePtr->foregroundLayerP,&gamePtr->spriteArray[kForegroundSprite]);
  389.         
  390.         // Add the layers to the world
  391.         SWAddSpriteLayer(gamePtr->spriteWorldP, gamePtr->backgroundLayerP);
  392.         SWAddSpriteLayer(gamePtr->spriteWorldP, gamePtr->playerLayerP);
  393.         SWAddSpriteLayer(gamePtr->spriteWorldP, gamePtr->foregroundLayerP);
  394.         
  395.         SetupSpriteGame(gamePtr);
  396.         if(gSecretCode[kBGAnimationCode])
  397.             SetupBackgroundSprite(&gamePtr->spriteArray[kBackgroundSprite], backgroundSpriteID);
  398.         if(gSecretCode[kFGAnimationCode])
  399.             SetupForegroundSprite(&gamePtr->spriteArray[kForegroundSprite], foregroundSpriteID);
  400.         
  401.         // Do initial drawing to the background
  402.         SWSetPortToBackGround(gamePtr->spriteWorldP);
  403.         // Now Draw the Background PICT
  404.         HLock((Handle)BackGroundPict);
  405.         DrawPicture(BackGroundPict, &gWindowP->portRect);
  406.         HUnlock((Handle)BackGroundPict);
  407.         DisposeHandle((Handle)BackGroundPict);
  408.         
  409.         if(err == noErr)
  410.         {
  411.             // Draw hour glass
  412.             hourGlassRect.top = kHourGlassTop;
  413.             hourGlassRect.left = kHourGlassLeft;
  414.             hourGlassRect.bottom = kHourGlassBottom;
  415.             hourGlassRect.right = kHourGlassRight;
  416.             timePict = GetPicture(kHourGlassPICTResID);
  417.             if(timePict == nil)
  418.                 CantFindResource();
  419.             HLock((Handle)timePict);
  420.             DrawPicture(timePict, &hourGlassRect);
  421.             HUnlock((Handle)timePict);
  422.             ReleaseResource((Handle)timePict);
  423.             // Frame the damage Rects, draw names
  424.             ForeColor(magentaColor);
  425.             BackColor(greenColor);
  426.             TextFont(kDrawTimeTextFont);
  427.             TextSize(12);
  428.             TextFace(bold | italic);
  429.             //Player 1
  430.             damageRect.top = kLifeRectTop-2;
  431.             damageRect.bottom = kLifeRectBottom+2;
  432.             damageRect.left = kP1LifeRectLeft-2;
  433.             damageRect.right = kP1LifeRectRight+2;
  434.             EraseRect(&damageRect);
  435.             MoveTo(damageRect.left,damageRect.top-2);
  436.             DrawString(gPlayer1File.sfFile.name);
  437.             // Player 2
  438.             damageRect.left = kP2LifeRectLeft-2;
  439.             damageRect.right = kP2LifeRectRight+2;
  440.             EraseRect(&damageRect);
  441.             MoveTo(damageRect.left,damageRect.top-2);
  442.             DrawString(gPlayer2File.sfFile.name);
  443.             // Reset the pens
  444.             ForeColor(blackColor);
  445.             BackColor(whiteColor);
  446.             // Add white area to damage rects
  447.             damageRect.top += 2;
  448.             damageRect.bottom -= 2;
  449.             //Player 1
  450.             damageRect.left = kP1LifeRectLeft;
  451.             damageRect.right = kP1LifeRectRight;
  452.             EraseRect(&damageRect);
  453.             //Player 2
  454.             damageRect.left = kP2LifeRectLeft;
  455.             damageRect.right = kP2LifeRectRight;
  456.             EraseRect(&damageRect);
  457.             // ... erase the time-rect - I just use damageRect for it here
  458.             damageRect.top = kTimeRectTop;
  459.             damageRect.left = kTimeRectLeft;
  460.             damageRect.bottom = kTimeRectBottom;
  461.             damageRect.right = kTimeRectRight;
  462.             EraseRect(&damageRect);
  463.             // plain text
  464.             TextFace(0);
  465.         }
  466.         SWSetPortToWindow(gamePtr->spriteWorldP);
  467.     }
  468.  
  469.     if (err != noErr)
  470.     {
  471.         MyDisposeSpriteGame(gamePtr);
  472.         return err;
  473.     }
  474.     
  475.     return err;
  476. }
  477.  
  478. void MyDisposeSpriteGame(SpriteGamePtr spriteGameP)
  479. {
  480.     SpriteLayerPtr curLayerP;
  481.     SpritePtr curSpriteP;
  482.     short i;
  483.  
  484.     if (gWorkRgn != NULL)
  485.         DisposeRgn(gWorkRgn);
  486.  
  487.     if (spriteGameP != NULL)
  488.     {
  489.         if (spriteGameP->spriteWorldP != NULL)
  490.         {
  491.             SWUnlockSpriteWorld(spriteGameP->spriteWorldP);
  492.  
  493.                 // dispose of each sprite in the layer
  494.             while ((curLayerP = SWGetNextSpriteLayer(spriteGameP->spriteWorldP, NULL)) != NULL)
  495.             {
  496.                 while ((curSpriteP = SWGetNextSprite(curLayerP, NULL)) != NULL)
  497.                 {
  498.                     SWRemoveSprite(curLayerP, curSpriteP);
  499.                     SWCloseSprite(curSpriteP); // Close, not dispose!
  500.                 }
  501.     
  502.                 SWRemoveSpriteLayer(spriteGameP->spriteWorldP, curLayerP);
  503.                 SWDisposeSpriteLayer(curLayerP);
  504.             }
  505.         }
  506.         if (spriteGameP->playerLayerP != NULL)
  507.         {
  508.             SWDisposeSpriteLayer(spriteGameP->playerLayerP);
  509.         }
  510.         if (spriteGameP->spriteWorldP != NULL)
  511.         {
  512.             SWDisposeSpriteWorld(spriteGameP->spriteWorldP);
  513.         }
  514.     }
  515.     // Release sounds
  516.     for(i=0; i<kNumSpriteSounds; i++)
  517.     {
  518.         HUnlock(gP1SoundH[i]);
  519.         DisposeHandle(gP1SoundH[i]);
  520.         HUnlock(gP2SoundH[i]);
  521.         DisposeHandle(gP2SoundH[i]);
  522.     }
  523.  
  524.     SWExitSpriteWorld();
  525. }
  526.  
  527. ///--------------------------------------------------------------------------------------
  528. // SetupSpriteGame
  529. ///--------------------------------------------------------------------------------------
  530. short gMoveDelta = 0;
  531. void SetupSpriteGame(SpriteGamePtr    gamePtr)
  532. {
  533.     Rect tempBoundsRect, moveBoundsRect;
  534.     short horizMoveDelta;
  535.     short vertMoveDelta;
  536.     short    i;
  537.     unsigned char    *spriteDataPtr; // use as an array of 8 u. chars.
  538.  
  539.     // Initialize sprite's userData
  540.     for(i=0; i<kNumberOfSprites; i++)
  541.     {
  542.         spriteDataPtr = (unsigned char *)(&gamePtr->spriteArray[i].userData);
  543.         spriteDataPtr[kPreviousAction] = aJump;
  544.         spriteDataPtr[kCurrentAction] = aJump;
  545.         spriteDataPtr[kSpriteLife] = kSpriteMaxLife;
  546.         spriteDataPtr[kSpriteBitData] = 0;
  547.         switch(i)
  548.         {
  549.             case kPlayer1Sprite:
  550.                 spriteDataPtr[kSpriteIDNum] = gPlayer1Controller;
  551.                 break;
  552.             case kPlayer2Sprite:
  553.                 spriteDataPtr[kSpriteIDNum] = gPlayer2Controller;
  554.                 break;
  555.             case kPlayer1ProjectileSprite:
  556.                 spriteDataPtr[kSpriteIDNum] = kPlayer1ProjectileSprite;
  557.                 break;
  558.             case kPlayer2ProjectileSprite:
  559.                 spriteDataPtr[kSpriteIDNum] = kPlayer2ProjectileSprite;
  560.                 break;
  561.             default: // who cares???
  562.                 break;
  563.         }
  564.     }
  565.     
  566.     moveBoundsRect.bottom = gamePtr->spriteWorldP->windowFrameP->frameRect.bottom - 32;
  567.     moveBoundsRect.top = gamePtr->spriteWorldP->windowFrameP->frameRect.top;
  568.     moveBoundsRect.left = gamePtr->spriteWorldP->windowFrameP->frameRect.left;
  569.     moveBoundsRect.right = gamePtr->spriteWorldP->windowFrameP->frameRect.right;
  570.     
  571.     gMoveDelta += 1;
  572.     tempBoundsRect = moveBoundsRect;
  573.     horizMoveDelta = gMoveDelta;        //GetRandom(2, 6);
  574.     vertMoveDelta =    gMoveDelta;        //GetRandom(2, 6);
  575.     
  576.     // calculate the movement boundary rectangle
  577.     InsetRect(&tempBoundsRect, horizMoveDelta, vertMoveDelta);
  578.     if (GetRandom(0, 1) == 1)
  579.         horizMoveDelta = -horizMoveDelta;
  580.  
  581.     if (GetRandom(0, 1) == 1)
  582.         vertMoveDelta = -vertMoveDelta;
  583.     
  584.     // set the player 1 & 2 sprite’s movement characteristics
  585.     for(i=kPlayer1Sprite; i<=kPlayer2Sprite; i++)
  586.     {
  587.         SWSetSpriteMoveBounds(&gamePtr->spriteArray[i], &tempBoundsRect);
  588.         SWSetSpriteMoveDelta(&gamePtr->spriteArray[i], horizMoveDelta, vertMoveDelta);
  589.         SWSetSpriteMoveProc(&gamePtr->spriteArray[i], CombatMoveProc); //• mine
  590.         // Maximum Speed!!!
  591.         SWSetSpriteMoveTime(&gamePtr->spriteArray[i], 5*(20-gFrameAdvanceTime-1));
  592.         SWSetSpriteFrameTime(&gamePtr->spriteArray[i], 5*(20-gFrameAdvanceTime-1));
  593.         SWSetSpriteFrameRange(&gamePtr->spriteArray[i], 0, kNumberOfWarriorFrames - 1);
  594.         SWSetSpriteFrameAdvance(&gamePtr->spriteArray[i], 1);
  595.         // Default = CopyBits
  596.         //SWSetSpriteDrawProc(&gamePtr->spriteArray[i], CompiledSpriteDrawProc); // Compiled Draw
  597.         // Sprite Blitzkrieg!
  598.         //SWSetSpriteDrawProc(&gamePtr->spriteArray[i], BlitPixieMaskDrawProc); // Blit
  599.         // Collision procedure
  600.         SWSetSpriteCollideProc(&gamePtr->spriteArray[i], CombatSpriteCollideProc); // mine
  601.         // set the sprite’s initial location
  602.         switch(i)
  603.         {
  604.             case kPlayer1Sprite:
  605.                 SWSetSpriteLocation(&gamePtr->spriteArray[i], 40, 40);
  606.                 break;
  607.             case kPlayer2Sprite:
  608.                 SWSetSpriteLocation(&gamePtr->spriteArray[i], (640-128), 40);
  609.                 break;
  610.         }
  611.     }
  612.     
  613.     // set the player 1 & 2 projectile’s movement characteristics
  614.     for(i=kPlayer1ProjectileSprite; i<=kPlayer2ProjectileSprite; i++)
  615.     {
  616.         // Reset some stuff
  617.         spriteDataPtr = (unsigned char *)(&gamePtr->spriteArray[i].userData);
  618.         spriteDataPtr[kPreviousAction] = aProjectileIdle;
  619.         spriteDataPtr[kCurrentAction] = aProjectileIdle;
  620.         spriteDataPtr[kSpriteLife] = kSpriteMaxLife;
  621.         tempBoundsRect.right += 200;
  622.         tempBoundsRect.left -= 200;
  623.         
  624.         SWSetSpriteMoveBounds(&gamePtr->spriteArray[i], &tempBoundsRect);
  625.         SWSetSpriteMoveDelta(&gamePtr->spriteArray[i], 0, 0);
  626.         SWSetSpriteMoveProc(&gamePtr->spriteArray[i], ProjectileMoveProc); //• mine
  627.         // Maximum Speed!!!
  628.         SWSetSpriteMoveTime(&gamePtr->spriteArray[i], 5*(20-gFrameAdvanceTime-1));
  629.         SWSetSpriteFrameTime(&gamePtr->spriteArray[i], 5*(20-gFrameAdvanceTime-1));
  630.         SWSetSpriteFrameRange(&gamePtr->spriteArray[i], 0, kNumberOfProjectileFrames - 1);
  631.         SWSetSpriteFrameAdvance(&gamePtr->spriteArray[i], 1);
  632.         // Invisible to start with
  633.         SWSetSpriteVisible(&gamePtr->spriteArray[i], FALSE);
  634.         // Collision procedure
  635.         SWSetSpriteCollideProc(&gamePtr->spriteArray[i], CombatSpriteCollideProc); // mine
  636.         // set the sprite’s initial location to zero (will update later when needed)
  637.         SWSetSpriteLocation(&gamePtr->spriteArray[i], 300, 300);
  638.     }
  639. }
  640.  
  641. void SpriteFuneral(short theWinner)
  642. {
  643.     PicHandle    victPict;
  644.     Rect        victRect;
  645.     
  646.     victRect.top = victRect.left = 0;
  647.     victRect.bottom = 78;
  648.     victRect.right = 253;
  649.     MyCenterRect(&victRect, &gWindowP->portRect);
  650.     
  651.     switch(theWinner)
  652.     {
  653.         case kPlayer1Sprite:
  654.             victPict = GetPicture(kP1WinPICTResID);
  655.             if(victPict == nil)
  656.                 DoError(kResError, TRUE);
  657.             HLock((Handle)victPict);
  658.             DrawPicture(victPict, &victRect);
  659.             HUnlock((Handle)victPict);
  660.             ReleaseResource((Handle)victPict);
  661.             PlaySpriteMovie(gPlayer1File);
  662.             break;
  663.         case kComputer1Sprite:
  664.             victPict = GetPicture(kComputerWinPICTResID);
  665.             if(victPict == nil)
  666.                 DoError(kResError, TRUE);
  667.             HLock((Handle)victPict);
  668.             DrawPicture(victPict, &victRect);
  669.             HUnlock((Handle)victPict);
  670.             ReleaseResource((Handle)victPict);
  671.             PlaySpriteMovie(gPlayer1File);
  672.             break;
  673.         case kPlayer2Sprite:
  674.             victPict = GetPicture(kP2WinPICTResID);
  675.             if(victPict == nil)
  676.                 DoError(kResError, TRUE);
  677.             HLock((Handle)victPict);
  678.             DrawPicture(victPict, &victRect);
  679.             HUnlock((Handle)victPict);
  680.             ReleaseResource((Handle)victPict);
  681.             PlaySpriteMovie(gPlayer2File);
  682.             break;
  683.         case kComputer2Sprite:
  684.             victPict = GetPicture(kComputerWinPICTResID);
  685.             if(victPict == nil)
  686.                 DoError(kResError, TRUE);
  687.             HLock((Handle)victPict);
  688.             DrawPicture(victPict, &victRect);
  689.             HUnlock((Handle)victPict);
  690.             ReleaseResource((Handle)victPict);
  691.             PlaySpriteMovie(gPlayer2File);
  692.             break;
  693.         default:
  694.             SysBeep(30);
  695.             break;
  696.     }
  697. }
  698.  
  699. short DetermineWinner(SpriteWorldPtr spriteWorldP)
  700. {
  701.     unsigned char    *data1Ptr, *data2Ptr, mostLifeForce=0, healthiestSprite;
  702.     
  703.     data1Ptr = (unsigned char *)(&spriteGame.spriteArray[kPlayer1Sprite].userData);
  704.     data2Ptr = (unsigned char *)(&spriteGame.spriteArray[kPlayer2Sprite].userData);
  705.     mostLifeForce = data1Ptr[kSpriteLife];
  706.     if(data2Ptr[kSpriteLife] > mostLifeForce)
  707.         healthiestSprite = data2Ptr[kSpriteIDNum];
  708.     else
  709.         healthiestSprite = data1Ptr[kSpriteIDNum];
  710.     return healthiestSprite;
  711. }